use std::ops::{Deref, DerefMut};

struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

struct MyBox2<T> {
    v: T,
}

impl<T> MyBox2<T> {
    fn new(x: T) -> MyBox2<T> {
        MyBox2 {v: x}
    }
}

impl<T> Deref for MyBox2<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.v
    }
}

impl<T> DerefMut for MyBox2<T> {
    // type Target = T;
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.v
    }
}

fn main() {
    // println!("Hello, world!");

    let y = MyBox::new(5);

    assert_eq!(5, *y);

    let owner = "hello".to_string();

    foo(&owner);

    println!("**2**");
    let mut s = "rust ".to_string();
    display(&mut s);
}

fn foo(s: &str) {
    println!("{s}");
}

fn display(s: &mut String) {
    s.push_str("world");
    println!("{s}");
}